<template>
  <div class="upload-list-layout">
    <el-upload
      class="upload-wrap"
      drag
      :headers="headers"
      :action="action"
      :accept="fileType"
      :multiple="multiple"
      :show-file-list="false"
      :http-request="action == '' ? handleUpload : undefined"
      :before-upload="beforeFileUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
    >
      <div class="el-upload__text">
        <img class="ic-16" src="@/assets/common/upload_3.png" />
        <span>点击上传</span>
      </div>
    </el-upload>
    <div class="upload-tip" v-if="uploadTip">{{ uploadTip }}</div>
    <div class="file-list" v-if="fileList.length">
      <div
        class="file-item"
        v-for="(item, index) in fileList"
        :key="index"
        :style="{ width: fileWidth }"
        :class="{ 'error-status': item.errorStatus }"
      >
        <el-image
          class="file-img"
          :src="item.link"
          fit="cover"
          v-if="checkFileType(item.fileName) == 'img'"
          :preview-src-list="preViewList"
        >
          <div slot="error" class="img-icon"></div>
        </el-image>
        <div
          class="file-left"
          :class="checkFileType(item.fileName)"
          v-else
        ></div>
        <div class="file-right">
          <div class="file-name">
            <el-tooltip
              effect="dark"
              :content="item.fileName"
              placement="top-start"
            >
              <div class="label" @click="downFileHandle(item)">
                {{ item.fileName }}
              </div>
            </el-tooltip>
            <div
              class="layout-close"
              @click="removeHandle(item)"
              v-if="
                item.percentage >= 100 ||
                item.errorStatus ||
                item.percentage === undefined
              "
            ></div>
            <div class="percentage" v-else>{{ item.percentage }}%</div>
          </div>
          <el-progress
            v-if="item.percentage < 100 && !item.errorStatus"
            style="margin-top: 6px"
            :percentage="item.percentage"
            color="#0087d6"
            :stroke-width="4"
            define-back-color="#F8F8F8"
            :show-text="false"
          ></el-progress>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getFileTypeByName } from "@/utils/fileType";
import { comExportFileByUrl, comExport } from "@/utils/util";
import { cloneDeep } from "lodash-es";
import Store from "@/store/index";
export default {
  name: "TrUploadFileListBox",
  props: {
    // 文件上传提示
    uploadTip: {
      type: String,
      default:
        "支持excel、pdf、doc、docx、txt、jpg、png等格式文件上传，文件大小不超过10MB，所有附件个数不超过9个",
    },
    action: {
      type: String,
      default: "",
    },
    multiple: {
      type: Boolean,
      default: true,
    },
    limitNum: {
      type: Number,
      default: 9,
    },
    // 文件类型
    fileType: {
      type: String,
      default: ".xlsx,.xls",
    },
    // 文件限制大小
    maxFileSize: {
      type: Number,
      default: 100,
    },
    title: {
      type: String,
      default: "数据导入",
    },
    value: {
      type: Array,
      default: () => [],
      required: true,
    },
    ftObject: {
      type: Object,
      default: () => {},
    },
    fileWidth: {
      type: String,
      default: "100%",
    },
  },
  computed: {
    preViewList() {
      return this.fileList
        .filter((item) => this.checkFileType(item.fileName) == "img")
        .map((val) => val.link);
    },
  },
  data: () => ({
    fileList: [],
    headers: {
      "Blade-Auth": "bearer " + Store.state.user.token,
    },
    fileLenth: 0,
  }),
  methods: {
    beforeFileUpload(file) {
      this.$message.closeAll();
      if (this.fileLenth >= this.limitNum) {
        this.$message.warning(`至多上传${this.limitNum}份附件！`);
        return false;
      }
      if (this.fileList.some((item) => item.fileName === file.name)) {
        this.$message.warning(`${file.name}已存在，请勿重复上传`);
        return false;
      }
      const fileType = file.name.split(".").pop();
      let fileTypeList = this.fileType
        .split(",")
        .map((item) => item.replace(/\./g, ""));
      if (!fileTypeList.includes(fileType)) {
        this.$message.error(`请上传${this.fileType}格式文件！`);
        return false;
      }
      const isMax = file.size / 1024 / 1024 < this.maxFileSize;
      if (!isMax) {
        this.$message.error(`上传文件大小不能超过${this.maxFileSize}M`);
        return false;
      }
      this.fileLenth += 1;
      if (!this.action) {
        file.fileName = file.name;
        this.fileList.push(file);
        this.timeCountDown(file);
        this.emitFileHandle();
        this.$emit("upload-back", this.ftObject);
      } else {
        this.$load.show();
      }
    },
    timeCountDown(file) {
      const targetFile = this.fileList.find((item) => item.uid === file.uid);
      this.$set(targetFile, "percentage", 0);
      this.$set(targetFile, "interval", null);
      targetFile.interval = setInterval(() => {
        targetFile.percentage = targetFile.percentage + 1;
        if (targetFile.percentage >= 99) {
          clearInterval(targetFile.interval);
        }
        this.$forceUpdate();
      }, 10);
      setTimeout(() => {
        targetFile.percentage = 100;
        this.$forceUpdate();
      }, 2000);
    },
    checkFileType(name) {
      return getFileTypeByName(name);
    },
    handleUpload() {},
    handleSuccess(res, file) {
      this.$load.close();
      res.data.fileName = res.data.originalName;
      let fileObject = Object.assign({}, file, res.data);
      this.fileList.push(fileObject);
      this.timeCountDown(file);
      this.emitFileHandle();
      this.$emit("upload-back", this.ftObject);
    },
    handleError(res, file) {
      this.$load.close();
      const targetFile = this.fileList.find((item) => item.uid === file.uid);
      if (targetFile) {
        clearInterval(targetFile.interval);
        this.$set(targetFile, "errorStatus", true);
      } else {
        file.errorStatus = true;
        file.fileName = file.name;
        this.fileList.push(file);
      }
      this.$message.error(this.$t("msg.uploadFailed"));
    },
    removeHandle(val) {
      let index = this.fileList.findIndex(
        (item) => item.fileName === val.fileName
      );
      this.fileList.splice(index, 1);
      this.fileLenth -= 1;
      this.emitFileHandle();
    },
    emitFileHandle() {
      let list = this.fileList.filter((item) => !item.errorStatus);
      this.$emit("input", list);
    },
    downFileHandle(file) {
      if (!this.action) return comExport(file, file.fileName);
      if (!file.link) return this.$message.error("下载失败，文件路径异常");
      comExportFileByUrl(file.link, file.fileName);
    },
  },
  created() {
    this.fileList = cloneDeep(this.value);
    this.fileLenth = this.fileList.length;
  },
};
</script>

<style lang="scss" scoped>
.upload-list-layout {
  height: 100%;
  width: 100%;
}
::v-deep.upload-wrap {
  font-size: 0;
  .el-upload-dragger {
    border-radius: 3px;
    background-color: #f3f3f3;
    border: 1px solid #dcdcdc;
    width: 100% !important;
    height: auto;
  }
  .el-upload__text {
    width: 112px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    font-size: 14px;
    span {
      margin-left: 8px;
      color: rgba(#000, 0.4);
      font-weight: 400;
      font-size: 14px;
    }
  }
}
.upload-tip {
  margin: 12px 0;
  color: rgba(#000, 0.4);
  font-size: 12px;
  word-break: break-all;
}
::v-deep .file-list {
  margin-top: 16px;
  max-height: 253px;
  overflow-y: auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  margin-bottom: -8px;
}
::v-deep .file-item {
  border-radius: 6px;
  background-color: #f8f8f8;
  border: 1px solid #e7e7e7;
  padding: 13px 16px;
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  .file-left {
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    &.excel {
      background-image: url("~@/assets/icons/excel.png");
      background-size: contain;
    }
    &.apk {
      background-image: url("~@/assets/icons/apk.png");
      background-size: contain;
    }
    &.doc {
      background-image: url("~@/assets/icons/doc.png");
      background-size: contain;
    }
    &.pdf {
      background-image: url("~@/assets/icons/pdf.png");
      background-size: contain;
    }
    &.txt {
      background-image: url("~@/assets/icons/txt.png");
      background-size: contain;
    }
    &.zip {
      background-image: url("~@/assets/icons/zip.png");
      background-size: contain;
    }
  }
  .file-img {
    width: 32px;
    height: 32px;
    .img-icon {
      width: 32px;
      height: 32px;
      background-image: url("~@/assets/icons/img.png");
      background-size: contain;
    }
  }
  .file-right {
    flex: 1;
    margin-left: 12px;
  }
  .file-name {
    display: flex;
    align-items: center;
    justify-content: space-between;
    .label {
      cursor: pointer;
      flex: 1;
      width: 0;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      color: rgba(#000, 0.6);
      font-weight: 500;
      font-size: 14px;
      margin-right: 8px;
    }
    .percentage {
      text-align: right;
      min-width: 36px;
      color: #0087d6;
      font-weight: 400;
      font-size: 12px;
    }
    .layout-close {
      width: 20px;
      height: 20px;
      background-image: url("~@/assets/icons/close_2.png");
      background-size: contain;
      cursor: pointer;
    }
  }
  &:hover {
    border-color: #0087d6;
    .file-name {
      .label {
        color: #0087d6;
      }
    }
  }
}
.error-status {
  .file-name {
    .label {
      color: #e34d59 !important;
    }
  }
}
</style>
